home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / pdclk139.zip / PDCLKSET.ASM < prev    next >
Assembly Source File  |  1992-05-17  |  41KB  |  1,861 lines

  1.  
  2. PAGE  44,132
  3.  
  4. ; Copyright (C) 1991 by Jan.Engvald@ldc.lu.se, see file COPYING.
  5.  
  6. ;========================================================================
  7.         include pdclkset.doc
  8. ;========================================================================
  9.  
  10. ESCAPE        equ    27
  11. RFCC            equ     TBLBUILD+PINGCLIENT     ; RFC compliance needed
  12.  
  13. if TBLBUILD
  14. PROGSTR     equ    'pdtbuild'
  15. else
  16. PROGSTR     equ    'pdclkset'
  17. endif ; TBLBUILD
  18.  
  19. IDSTRING    equ    PROGSTR,PRGVERSION
  20.  
  21.  
  22.         include defs.asm
  23.  
  24. ;************************************************************************
  25. ;*        Start of segment (PSP data)                *
  26. ;************************************************************************
  27.  
  28.         .386        ; (to avoid masm expression overflow)
  29.   
  30. code_s        segment use16
  31.         assume    cs:code_s, ds:code_s, es:code_s
  32.  
  33.         org    0
  34. CodeOrg     label    byte
  35. PspInt20    dw    ?
  36. PspTopMem    dw    ?
  37.  
  38.         org    5Ch            ; PSP reused for data
  39.  
  40.         org    80h            ; PSP command parameter area  
  41. phd_dioa    db    ?
  42.         db    ?            ; always a space
  43. phd_string    db    ?
  44.  
  45.  
  46. ;************************************************************************
  47. ;*        Start of segment (code)                 *
  48. ;************************************************************************
  49.  
  50.         org    100h
  51. StackEnd    equ    $            ; 80h-100h is interupt stack
  52. SaveSP        equ    $
  53. SaveSS        equ    SaveSP+2
  54.  
  55. start:        jmp    start1            ; jump over data area
  56.         nop
  57.  
  58. id_label    db    IDSTRING
  59.  
  60.   
  61. ;************************************************************************
  62. ;*                                    *
  63. ;*        Data area                        *
  64. ;*                                    *
  65. ;************************************************************************
  66.  
  67. NotEnoughMsg    db    LF, "Need to know at least IP nr, Offset and Timeserver$"
  68. OccupiedMsg    db    LF, "My IP nr is already in use by another host with hardware addr "
  69. OccupiedHw    db    "00:00:00:00:00:00$"
  70. MsgNoConect     db      LF, "No response from target host$"
  71. NoBotReplyMsg    db    LF, "No BOOTP reply$"
  72. NoGwyMsg    db    LF, "Need to know a gateway (or wrong mask)$"
  73. NoTimeServMsg    db    LF, "No reply from time server$"
  74.  
  75. usage_msg    db    LF
  76.   db  "Copyright (C) 1991 by Jan.Engvald@ldc.lu.se, see file COPYING.", CR, LF
  77.   db  IDSTRING, ' ', ??date, " usage to set the PC clock from an UDP/IP TIME server:", CR, LF, LF
  78. ; db  "pdclkset b[ootp]       or", CR, LF, LF, LF
  79.   db  PROGSTR," [o[ffset]=time]   (time is [-|+][<hours>h][<minutes>m][<seconds>[s]])", CR, LF, LF
  80.   db  "         [d[aylightsave]=PAC | USA | CUB | CHIL | BRZ | GBR |", CR, LF
  81.   db  "                         W_EU | M_EU | E_EU | LIBY | EGY | TURK | ISR |", CR, LF
  82.   db  "                         IRAN | PRC | ROK | AUS | TASM | NSW | LHI | NZE |", CR, LF
  83.   db  "                  FrTime,FrWeekDay,FrDayOfYear,ToTime,ToWday,ToDayOfYr,AddTime]", CR, LF, LF
  84.   db  "         [i[pnr]=n.n.n.n]  [t[imserver]=n.n.n.n[,n.n.n.n[,...]]]", CR, LF, LF
  85.   db  "         [m[ask]=n.n.n.n  g[ateway]=n.n.n.n[,n.n.n.n[,...]]]  [f[lags]=flagnr]", CR, LF, LF
  86.   db  "         [z[onename]= # | variable=normalname,dlsname]  [a[lter]=days,time]", CR, LF, LF
  87.   db  "         [p[ktintno]=hexnr]"
  88. if PINGCLIENT
  89.   db  "  [e[cho]=name|n.n.n.n [,size,interval[,data,inc]]]", CR, LF, LF
  90.   db  "         [n[ameserver]=n.n.n.n[,n.n.n.n[,...]]]"
  91. endif ; PINGCLIENT
  92.   db  CR, LF, LF
  93.   db  "Example: ",PROGSTR," o= -1h  d=M_EU  z=#   (my IP nr and timeserver(s) from BOOTP)", CR, LF
  94.   db  "         ",PROGSTR," offs= 6h dst= USA zonename= tz=CST,CDT   (sets TZ=CST or CDT)", CR, LF
  95.   db  "         ",PROGSTR," o=8h  d=PAC  ip=123.45.6.7  ts=123.45.6.8    (BOOTP not used)"
  96.  
  97. if PINGCLIENT
  98.   db  CR, LF, "         ",PROGSTR," pktdrv= 0x7c  echo= ping.lu.se      (ping client)"
  99. endif
  100. if TBLBUILD
  101.   db  CR, LF, "         ",PROGSTR," flags= 2+4   (address table builder for LANwatch)"
  102. endif
  103.         db    '$'
  104. crlf_msg        db      CR, LF, '$'
  105.  
  106. MsgNotSet    db    CR, LF
  107.         db    "***************************************", CR, LF, 7
  108.          db    "*                                     *", CR, LF, 7
  109.         db    "* Could not set correct date and time *", CR, LF
  110.          db    "*                                     *", CR, LF
  111.         db    "***************************************", CR, LF, "$"
  112.  
  113. MsgTerm        db    CR, LF, "End of ", IDSTRING, ", error="
  114. MsgTermNr    db    255, ", HWaddr "
  115. MsgTermHw    db    "00:00:00:00:     , IP nr "
  116. MsgMyIp        db    "1.2.3.4        ", CR, LF
  117. MsgTermStop    db    "$", 7, Cr, LF, 7
  118.         db    "Dst entries too old, update and reassemble PDCLKSET", CR, LF, '$'
  119.  
  120.         even
  121. Flagword    dw    0
  122. DONT_SETTIME    equ    1
  123. HAVE_MYIPNR    equ    2
  124. HAVE_TIMEOFFSET equ    4
  125. HAVE_TIMESERVER equ    8
  126.  
  127. HAVE_ENOUGH    equ    HAVE_MYIPNR + HAVE_TIMEOFFSET + HAVE_TIMESERVER
  128. EnoughWord    dw    HAVE_ENOUGH
  129.  
  130. ArgFlags    dw    0
  131. TERM_WAIT    equ    1
  132. MAKE_TABLE    equ    2
  133. LANW_TABLE    equ    4
  134. TBL_PROBE    equ    8
  135. TIM_NOHIRES    equ    16
  136.  
  137. MAXTSERVS    equ    4
  138. RespondingIpNr    dw    0, 0
  139.  
  140. TservNum    dw    0
  141. TimeServIpNr    dw    MAXTSERVS*2 dup(0)
  142.  
  143. Sday        equ    3600*24
  144.  
  145. days        macro    incval
  146.         dd    x*Sday
  147. x        =    x+incval
  148.         endm
  149.  
  150. Ytab:
  151. x        =    15*366 + 49*365     ; start at 1964
  152.         rept    16
  153.         days    366
  154.         days    365
  155.         days    365
  156.         days    365
  157.         endm                ; ends on year 2027
  158.  
  159. Motab:                        ; normal year
  160. x        =    0
  161.         days    31    jan
  162.         days    28    feb
  163.         days    31    mar
  164.         days    30    apr
  165.         days    31    may
  166.         days    30    jun
  167.         days    31    jul
  168.         days    31    aug
  169.         days    30    sep
  170.         days    31    oct
  171.         days    30    nov
  172.         days    31    dec
  173.         days    1
  174.  
  175. Mltab:                        ; leap yer 
  176. x        =    0
  177.         days    31    jan
  178.         days    29    feb
  179.         days    31    mar
  180.         days    30    apr
  181.         days    31    may
  182.         days    30    jun
  183.         days    31    jul
  184.         days    31    aug
  185.         days    30    sep
  186.         days    31    oct
  187.         days    30    nov
  188.         days    31    dec
  189.         days    1
  190.  
  191. Weekdays    db    "   Sun"
  192.         db    "   Mon"
  193.         db    "  Tues"
  194.         db    "Wednes"
  195.         db    " Thurs"
  196.         db    "   Fri"
  197.         db    " Satur"
  198.  
  199.  
  200. AlgTab        AlgData <>
  201. AlgTabEnd    equ    $
  202.  
  203. AlgPtr    dw    0
  204.  
  205. m6hour        dw    6*3600
  206. m12hour     dw    12*3600
  207. mhour        dw    3600
  208. m60b        db    60,0
  209. m7        dw    7
  210. m6        db    6
  211. m1        dw    1
  212.  
  213. cWday        dw    0
  214. cYear        dw    0
  215. cMonth        dw    0
  216. cDay        dw    0
  217. cHour        dw    0
  218. cMinute     dw    0
  219. cSecond     dw    0
  220.  
  221. cNonLeapYear    db    0, 0
  222. cDayOfYear    dw    0
  223. cTime        dw    0, 0
  224. AlterTime    dw    0, 0, 0
  225. tzoffset    dw    0, 0
  226. DstAdvance    dw    0, 0
  227.  
  228. msgweek     =    $+13
  229. msgyear     =    $+23
  230. msghour     =    $+37
  231. msgset        db    'Clock set to Wednesday 1989-10-21 at 18:21:15'
  232. msgts        =    $+11
  233.         db    ' from host 1.2.3.4       ', '$'
  234.  
  235.  
  236. ;**********************************************************************
  237. ;*
  238. ;*        End of data area
  239. ;*
  240. ;**********************************************************************
  241.  
  242.         .8086    ; ensure no 386-only instructions
  243.  
  244. MULTIPROCESS    equ    1        ; (the interrupt process counts here)
  245.  
  246. PushfDI     macro
  247. if    MULTIPROCESS
  248.         pushf                ; save enable interrupt flag
  249.         cli                ; and disable interrupt
  250. endif ; MULTIPROCESS
  251.         endm
  252.  
  253. PopfEI        macro
  254. if    MULTIPROCESS
  255.         popf                ; restore enable interrupt flag
  256. endif ; MULTIPROCESS
  257.         endm                ; (probably enabling interrupt)
  258.  
  259.  
  260.  
  261. ;************************************************************************
  262. ;*        Something2Do
  263. ;*
  264. ;* Simulates a task scheduler.
  265. ;*
  266. ;*    Destroys:    flags
  267. ;************************************************************************
  268.  
  269. Something2Do    proc    near
  270.         push    ax
  271.         push    bx
  272.         push    cx
  273.         push    dx
  274.         push    si
  275.         push    di
  276.         push    bp
  277.         push    es
  278.         push    ds
  279. if RFCC
  280.         mov    di,offset IcmpToDo
  281.         call    GetFromList
  282.         jz    SomethingNxt4
  283.         mov    cx,[bx].dPktLen     ; (actually IP data length)
  284.         call    SendIcmpPkt
  285.         call    BufRelease
  286.   SomethingNxt4:
  287. endif ; RFCC
  288.         mov    di,offset SendToDo
  289.         call    GetFromList
  290.         jz    SomethingNxt2
  291.         call    SendAndWait
  292.         call    BufRelease
  293.   SomethingNxt2:
  294. if TBLBUILD
  295.         cmp    sp,offset StackLow+6*16    ; avoid overload
  296.         jb    SomethingNxt5
  297.         call    TblProbe
  298.         mov    di,offset TblToDo
  299.         call    GetFromList
  300.         jz    SomethingNxt5
  301.         call    DoTable
  302.   SomethingNxt5:
  303. endif ; TBLBUILD
  304.  
  305. if TBLBUILD or PINGCLIENT
  306.         mov    di,offset NameToDo
  307.         call    GetFromList
  308.         jz    SomethingNxt6
  309.         call    DoNsInterp
  310.         call    BufRelease
  311.   SomethingNxt6:
  312. endif ; TBLBUILD or PINGCLIENT
  313.  
  314. if RFCC
  315.         mov    ax,SendToDo.lBufsAvail
  316.         add    ax,IcmpToDo.lBufsAvail
  317. endif ; RFCC
  318. if TBLBUILD
  319.         add    ax,TblToDo.lBufsAvail
  320. endif ; TBLBUILD
  321. if TBLBUILD or PINGCLIENT
  322.         add    ax,NameToDo.lBufsAvail
  323. endif ; TBLBUILD or PINGCLIENT
  324.         pop    ds
  325.         pop    es
  326.         pop    bp
  327.         pop    di
  328.         pop    si
  329.         pop    dx
  330.         pop    cx
  331.         pop    bx
  332.         pop    ax
  333.         ret
  334. Something2Do    endp
  335.  
  336.  
  337.  
  338.         include pktdr.asm
  339.  
  340.         include pkterr.asm
  341.  
  342.         include movemem.asm
  343.  
  344. ARPSLOTS    equ    8 + 4*TBLBUILD
  345. ROUTESLOTS    equ    5
  346. MAXDEFGWYS    equ    4 + 6*TBLBUILD
  347. MAXDEFNS    equ    3
  348.  
  349. SNAP        equ    0
  350.  
  351. NBUFSMALM    equ    24            ; at least so many small bufs
  352.  
  353. ;========================================================================
  354.          include bufs.asm
  355.  
  356. ;========================================================================
  357.          include ip.asm
  358.  
  359.  
  360. ;========================================================================
  361.          include arp.asm
  362.  
  363. ;************************************************************************
  364. ;*        MakeSendDescr
  365. ;************************************************************************
  366.  
  367. MakeSendDescr    proc    near
  368.         push    si
  369.         mov    [bx].dSqDelay,0
  370.         mov    [bx].dWaitEvent,0
  371.         mov    [bx].dTimOutMsg,offset MsgNoConect
  372.         mov    [bx].dTickTimeout,4*18
  373.         mov    [bx].dTickResend,1*18
  374.         lea    di,[bx+DESCRLEN]
  375.         mov    [bx].dPtrPhys,di
  376.         lea    si,[di]+GIANT
  377.         mov    [bx].dPktEnd,si
  378.         add    di,H2Len
  379.         add    di,2
  380.         xor    cx,cx
  381.         test    GenFlags,USE_SNAP
  382.         jz    MakeNotSnap
  383.         add    di,8            ; snap
  384.         inc    cx
  385.   MakeNotSnap:
  386.         mov    [bx].dSnap,cl
  387.         mov    [bx].dPtrIp,di
  388.         mov    cx,IPHDRLEN
  389.         mov    si,offset IpHdr
  390.         push    cs
  391.         pop    es
  392.         call    movemem         ; copy IP hdr prototype
  393.         mov    [bx].dPtrUdp,di
  394.         pop    si
  395.         ret
  396. MakeSendDescr    endp
  397.  
  398.  
  399.  
  400.  
  401. ;************************************************************************
  402. ;************************************************************************
  403. ;*
  404. ;*        Input and Output routines
  405. ;*
  406. ;************************************************************************
  407. ;************************************************************************
  408.  
  409.  
  410. PutNumFiller    db    '0'
  411.         even
  412. GetNumBase    dw    10
  413. PutNumBase    dw    10
  414. PutMinDigits    dw    2
  415. k10000        dw    10000
  416.  
  417. IntTmpHwAd    dw    0, 0, 0, 0, 0, 0
  418. IntTmpIpNr    equ    IntTmpHwAd
  419.  
  420.  
  421.  
  422. ;************************************************************************
  423. ;*        SkipPastEq
  424. ;************************************************************************
  425.  
  426. SkipPastEq    proc    near
  427.         mov    cx,30            ; max name length
  428.   SkipLook4Eq:
  429.         cmp    al,'='            ; look for equal sign
  430.         je    SkipFoundEq
  431.         cmp    al,':'            ; colon is alias for equal
  432.         je    SkipFoundEq        ; (batch parameters need it)
  433.  
  434.         lodsb
  435.         loop    SkipLook4Eq
  436.   SkipFoundEq:
  437.         call    skip_blanks        ; blanks may follow
  438.  
  439.         ret
  440. SkipPastEq    endp
  441.  
  442.  
  443.  
  444. ;************************************************************************
  445. ;*        GetNums
  446. ;************************************************************************
  447.  
  448. GetNums     proc    near
  449.         mov    ch,','            ; comma separated numbers
  450.         jmp    short GetSkipBlanks
  451. GetNumsDot:
  452.         mov    ch,'.'            ; dot separated numbers
  453.   GetSkipBlanks:
  454.         push    bx
  455.         mov    bx,cx
  456.         call    skip_blanks
  457.   GetNextNum:
  458.         call    GetNum            ; get a number
  459.         stosw                ; store it in table
  460.         dec    bl            ; do we want more nums?
  461.         jz    GetNumsRet        ; - no, return
  462.  
  463.         lodsb                ; - yes
  464.         cmp    al,bh            ; is this a separator char?
  465.         je    GetNextNum        ; - yes
  466.   GetNumsRet:                    ; - no, return
  467.         pop    bx
  468.         ret
  469. GetNums     endp
  470.  
  471.  
  472.  
  473. ;************************************************************************
  474. ;*        GetNum
  475. ;************************************************************************
  476.  
  477. GetNum        proc    near
  478.         xor    dx,dx
  479.         lodsb
  480.         cmp    al,'-'            ; minus prefix?
  481.         pushf
  482.         je    GetNumSign
  483.         cmp    al,'+'            ; plus prefix?
  484.         jne    GetNoPrefix
  485.   GetNumSign:
  486.         lodsb                ; get a char
  487.   GetNoPrefix:
  488.         mov    GetNumBase,10
  489.         cmp    al,'0'            ; hex leading '0x' ?
  490.         jne    GetNextDig
  491.         cmp    byte ptr [si],'X'
  492.         je    GetNextHex
  493.         cmp    byte ptr [si],'x'
  494.         jne    GetNextDig
  495.   GetNextHex:
  496.         inc    si
  497.         mov    GetNumBase,16
  498.         lodsb
  499.   GetNextDig:
  500.         cmp    al,'0'            ; a digit?
  501.         jb    GetNumEnd
  502.         cmp    al,'9'
  503.         ja    GetTstHex
  504.  
  505.         sub    al,'0'            ; convert to integer
  506.         jmp    short GetNumConv
  507.   GetTstHex:
  508.         cmp    al,'A'
  509.         jb    GetNumEnd
  510.         cmp    al,'F'
  511.         ja    GetTstHex2
  512.         sub    al,'A'-10
  513.         jmp    short GetNumConv
  514.   GetTstHex2:
  515.         cmp    al,'a'
  516.         jb    GetNumEnd
  517.         cmp    al,'f'
  518.         ja    GetNumEnd
  519.         sub    al,'a'-10
  520.   GetNumConv:
  521.         cbw
  522.         add    ax,dx
  523.         mov    cx,ax
  524.         mul    GetNumBase
  525.         mov    dx,ax
  526.         lodsb
  527.         jmp    short GetNextDig
  528.   GetNumEnd:
  529.         mov    dx,60*60
  530.         cmp    al,'h'            ; hours suffix?
  531.         je    GetNumScale
  532.  
  533.         mov    dx,60
  534.         cmp    al,'m'            ; minutes suffix?
  535.         je    GetNumScale
  536.  
  537.         mov    dx,1
  538.         cmp    al,'s'            ; seconds suffix?
  539.         je    GetNumScale
  540.  
  541.         dec    si            ; move back char ptr
  542.   GetNumScale:
  543.         mov    ax,cx            ; do suffix scaling
  544.         mul    dx
  545.  
  546.         cmp    byte ptr [si],'+'    ; composite number?
  547.         je    GetComposite
  548.         cmp    byte ptr [si],'-'
  549.         je    GetComposite
  550.         cmp    byte ptr [si],'0'
  551.         jb    GetSingle
  552.         cmp    byte ptr [si],'9'
  553.         ja    GetSingle
  554.   GetComposite:
  555.         push    di            ; save partial value
  556.         mov    cx,ax
  557.         push    cx
  558.         mov    di,dx
  559.         call    GetNum            ; get next part
  560.         pop    cx
  561.         add    ax,cx            ; add to previous part
  562.         adc    dx,di
  563.         pop    di
  564.   GetSingle:
  565.         popf                ; minus prefix?
  566.         jne    GetNumRet
  567.  
  568.         not    dx            ; make number negative
  569.         not    ax
  570.         add    ax,1
  571.         adc    dx,0 
  572.  GetNumRet:
  573.         cmp    ax,ax            ; ensure zero flag
  574.         ret
  575. GetNum        endp
  576.  
  577.  
  578.  
  579. ;************************************************************************
  580. ;*        GetIpNr
  581. ;************************************************************************
  582.  
  583. GetIpNr     proc    near
  584.         mov    cx,1
  585. GetIpNums:
  586.         push    cs
  587.         pop    es
  588.         push    cx            ; remember how many we wanted
  589.   GetIpCont:
  590.         push    cx            ; IP #'s left to read
  591.  
  592.         push    di
  593.         mov    cl,4
  594.         mov    di,offset IntTmpIpNr
  595.         call    GetNumsDot        ; read an IP #
  596.         mov    cx,4
  597.         pop    di
  598.         jnz    GetIpNrErr
  599.  
  600.         push    si
  601.         mov    si,offset IntTmpIpNr
  602.   GetIpNrLoop:
  603.         lodsw                ; convert to bytes
  604.         stosb
  605.         loop    GetIpNrLoop
  606.  
  607.         pop    si
  608.         pop    cx            ; want more IP #'s?
  609.         loop    GetIpMore
  610.   GetIpNrRet:
  611.         pop    ax
  612.         sub    ax,cx            ; ax = IP #'s read
  613.         cmp    cx,cx            ; zero flag
  614.         ret
  615.  
  616.   GetIpMore:
  617.         lodsb
  618.         cmp    al,','            ; comma separator?
  619.         je    GetIpCont
  620.  
  621.         dec    si
  622.         jmp    short GetIpNrRet
  623.  
  624.   GetIpNrErr:
  625.         pop    cx
  626.         pop    cx
  627.         ret                ; non-zero return
  628. GetIpNr     endp
  629.  
  630.  
  631.  
  632. ;************************************************************************
  633. ;*        PutIpNum (4 bytes from DS:SI to decimal at ES:DI)
  634. ;************************************************************************
  635.  
  636. PutIpNum    proc    near
  637.         push    di
  638.         push    es
  639.         push    cs
  640.         pop    es
  641.         mov    cx,4
  642.         mov    di,offset IntTmpIpNr
  643.         xor    ah,ah
  644.   PutIpLoop:
  645.         lodsb                ; convert IP #
  646.         stosw                ;  into integers
  647.         loop    PutIpLoop
  648.         pop    es
  649.         pop    di
  650.  
  651.         push    ds
  652.         push    cs
  653.         pop    ds
  654.         mov    si,offset IntTmpIpNr
  655.         mov    ch,'.'
  656.         mov    cl,4
  657.         mov    PutMinDigits,1
  658.         call    PutNums         ; put IP #
  659.         pop    ds
  660.         ret
  661. PutIpNum    endp
  662.  
  663.  
  664.  
  665. ;************************************************************************
  666. ;*        PutHwNum
  667. ;************************************************************************
  668.  
  669. PutHwNum    proc    near
  670.         push    di
  671.         push    cs
  672.         pop    es
  673.         mov    cx,6
  674.         mov    di,offset IntTmpHwAd
  675.         xor    ah,ah
  676.   PutHwLoop:
  677.         lodsb                ; convert HW #
  678.         stosw                ;  into integers
  679.         loop    PutHwLoop
  680.         pop    di
  681.  
  682.         push    cs
  683.         pop    ds
  684.         mov    si,offset IntTmpHwAd
  685.         mov    ch,'-'            ; separator char
  686.         test    ArgFlags,LANW_TABLE
  687.         jz    PutHwDash
  688.         mov    ch,7fh            ;   except for LANwatch table
  689.   PutHwDash:
  690.         mov    cl,6
  691.         mov    PutNumBase,16
  692.         mov    PutMinDigits,2
  693.         mov    PutNumFiller,'0'
  694.         call    PutNums         ; put HW #
  695.         mov    PutNumBase,10
  696.         ret
  697. PutHwNum    endp
  698.  
  699.  
  700.  
  701. ;************************************************************************
  702. ;*        PutNums
  703. ;************************************************************************
  704.  
  705. PutNumsD4    proc    near
  706.         mov    PutMinDigits,4
  707. PutNums:
  708.   NextNum:
  709.         lodsw                ; get integer from table
  710.         call    PutNum            ; convert to decimal
  711.         dec    cl            ; any more #'s?
  712.         jz    PutNumsRet
  713.  
  714.         cmp    ch,7fh            ; no separator char?
  715.         je    NextNum
  716.  
  717.         mov    al,ch
  718.         stosb                ; put separator char
  719.         jmp    short NextNum
  720.   PutNumsRet:
  721.         ret
  722. PutNumsD4    endp
  723.  
  724.  
  725.  
  726. ;************************************************************************
  727. ;*        PutNum
  728. ;************************************************************************
  729.  
  730. PutNumD2    proc    near
  731.         mov    PutMinDigits,2
  732. PutNum:
  733.         xor    dx,dx
  734. PutBigNum:
  735.         push    bx
  736.         push    cx
  737.         xor    cx,cx            ; extract significant digits
  738.         mov    bx,dx
  739.         cmp    PutNumBase,10
  740.         jne    NextDig
  741.         div    k10000
  742.         mov    bx,ax
  743.         mov    ax,dx
  744.   NextDig:
  745.         xor    dx,dx
  746.         div    PutNumBase
  747.         add    dx,'0'
  748.         cmp    dx,'9'
  749.         jle    PutNotHex
  750.  
  751.         add    dx,'a'-'9'-1
  752.   PutNotHex:
  753.         push    dx
  754.         inc    cx
  755.         or    ax,ax
  756.         jnz    NextDig
  757.  
  758.         or    bx,bx
  759.         jz    PutFiller
  760.  
  761.         mov    al,'0'
  762.   PutZeroNext:
  763.         cmp    cx,4
  764.         jae    PutZeroNumbr
  765.  
  766.         push    ax
  767.         inc    cx
  768.         jmp    short PutZeroNext
  769.   PutZeroNumbr:
  770.  
  771.         mov    ax,bx
  772.   NextDig2:
  773.         xor    dx,dx
  774.         div    PutNumBase
  775.         add    dx,'0'
  776.         push    dx
  777.         inc    cx
  778.         or    ax,ax
  779.         jnz    NextDig2
  780.   PutFiller:
  781.         mov    al,PutNumFiller
  782.   PutFillNext:
  783.         cmp    cx,PutMinDigits     ; want more digits?
  784.         jae    PutDigNumbr
  785.  
  786.         push    ax
  787.         inc    cx
  788.         jmp    short PutFillNext
  789.   PutDigNumbr:
  790.         mov    dx,cx            ; save DX = # of digits
  791.   PutDigs:
  792.         pop    ax
  793.         stosb                ; put the digits
  794.         loop    PutDigs
  795.  
  796.         pop    cx
  797.         pop    bx
  798.         ret
  799. PutNumD2    endp
  800.  
  801.  
  802.  
  803. ;************************************************************************
  804. ;*        PutBigNums
  805. ;************************************************************************
  806.  
  807. PutBigNums    proc    near
  808.   PutBigNext:
  809.         lodsw
  810.         mov    dx,ax
  811.         lodsw
  812.  
  813.         call    PutBigNum
  814.         loop    PutBigNext
  815.  
  816.         ret
  817. PutBigNums    endp
  818.  
  819.  
  820.  
  821. ;************************************************************************
  822. ;*        SkipBlk
  823. ;************************************************************************
  824.  
  825.         include skipblk.asm
  826.  
  827. ;************************************************************************
  828. ;*        ChrOut
  829. ;************************************************************************
  830.  
  831.         include chrout.asm
  832.  
  833.  
  834.  
  835.  
  836. ;************************************************************************
  837. ;************************************************************************
  838. ;*                                    *
  839. ;*        Program begins                        *
  840. ;*                                    *
  841. ;************************************************************************
  842. ;************************************************************************
  843.  
  844.  
  845. start1:
  846.         call    BufInit         ; initialize buffers
  847.         call    DoArgs            ; decode arguments
  848.         call    FindPktint        ; find the packet driver
  849.         call    InitArp         ; initialize ARP protocol
  850.         call    InitIp            ; initilize IP protocol
  851.  
  852.         test    ArgFlags,TERM_WAIT+MAKE_TABLE ; if we build tables
  853.         jnz    NeedIpOnly
  854. if PINGCLIENT
  855.         cmp    EchoTarget,0        ;   or do pinging
  856. endif ; PINGCLIENT
  857.         jz    MustHave
  858.   NeedIpOnly:
  859.         mov    EnoughWord,HAVE_MYIPNR    ;   time things not needed
  860.   MustHave:
  861.         mov    dx,Flagword
  862.         and    dx,EnoughWord
  863.         cmp    dx,EnoughWord        ; do we have needed info?
  864.         jne    UseBootp
  865.  
  866.         call    ValidateIpNr        ; - yes. IP # occupied?
  867.         jmp    short SkipBootp
  868.   UseBootp:
  869.         call    DoBootpPkt        ; - no, ask a bootp server
  870.         call    InterpBootp
  871.   SkipBootp:
  872.         mov    dx,Flagword
  873.         and    dx,EnoughWord
  874.         cmp    dx,EnoughWord        ; do we NOW have needed info?
  875.         je    DoTime
  876.  
  877.         mov    dx,offset NotEnoughMsg
  878.         mov    ah,9
  879.         int    21h
  880.         mov    al,07            ; error code 7
  881.         jmp    short SkipTime
  882.   DoTime:
  883.         call    MakeMynet        ; process mask and IP #
  884.  
  885.         cmp    EnoughWord,HAVE_MYIPNR
  886.         je    DidntGetIt
  887.  
  888.         call    GetTime         ; ask the time server
  889.         jnz    DidntGetIt
  890.         call    SetTime         ; set the PC clock
  891.         call    SetZone         ; set zone environment name
  892.   DidntGetIt:
  893. if TBLBUILD
  894.         call    TableInit
  895. endif ; TBLBUILD
  896.  
  897. if PINGCLIENT
  898.                 call    EchoAwhile              ; do some ping?
  899. endif ; PINGCLIENT
  900.                 call    DelayTermin             ; keep it running some more?
  901.         mov    al,00            ; error code 0
  902.   SkipTime:
  903.         call    terminate
  904.  
  905. ;************************************************************************
  906. ;************************************************************************
  907. ;*        End of program                        *
  908. ;************************************************************************
  909. ;************************************************************************
  910.  
  911.  
  912.  
  913. ;************************************************************************
  914. ;*        DoArgs
  915. ;************************************************************************
  916.  
  917.  
  918. ArgTabEnt    struc
  919. ArgTabNam    db    'a'            ; first char of arg name
  920. ArgTabAdr    dw    0            ; arg name handler
  921. ARGTABLEN    equ    $-ArgTabNam
  922. ArgTabEnt    ends
  923.  
  924. ArgTab        ArgTabEnt    <'a', offset ArgAlter>
  925.         ArgTabEnt    <'d', offset ArgDls>
  926. if PINGCLIENT
  927.         ArgTabEnt    <'e', offset ArgEcho>
  928. endif ; PINGCLIENT
  929.         ArgTabEnt    <'f', offset ArgFlag>
  930.         ArgTabEnt    <'g', offset ArgGwy>
  931.         ArgTabEnt    <'i', offset ArgIpnr>
  932.         ArgTabEnt    <'m', offset ArgMask>
  933. if TBLBUILD or PINGCLIENT
  934.         ArgTabEnt    <'n', offset ArgNameserv>
  935. endif ; TBLBUILD or PINGCLIENT
  936.         ArgTabEnt    <'o', offset ArgOffset>
  937.         ArgTabEnt    <'p', offset ArgPktIntNo>
  938.         ArgTabEnt    <'t', offset ArgTimeserv>
  939.         ArgTabEnt    <'z', offset ArgZoneNam>
  940. ArgTabEnd    equ    $
  941.  
  942. DoArgs        proc    near
  943.         mov    si,offset phd_dioa
  944.         lodsb
  945.         xor    ah,ah
  946.         mov    bp,ax
  947.         add    bp,si            ; end of args
  948.         call    skip_blanks
  949.         cmp    al,CR            ; no args?
  950.         je    ArgError        ; - yes, display usage msg
  951.  
  952.   NextArg:
  953.         call    skip_blanks
  954.         cmp    si,bp
  955.         ja    ArgError
  956.  
  957.         or    al,020h         ; conv to lower case
  958.  
  959.         cmp    al,'b'            ; bootp only, no args
  960.         je    DoArgRet
  961.  
  962.         cmp    al,CR+020h        ; end
  963.         je    DoArgRet
  964.  
  965.         mov    bx,offset ArgTab-ARGTABLEN
  966.   ArgFindLoop:
  967.         add    bx,ARGTABLEN
  968.         cmp    bx,offset ArgTabEnd
  969.         jae    ArgError
  970.         cmp    al,[bx]            ; first char of arg name
  971.         jne    ArgFindLoop
  972.  
  973.         call    SkipPastEq        ; skip rest of name
  974.         inc    bx
  975.         call    [bx]            ; process arg
  976.         jz    NextArg            ; look for next arg
  977.  
  978.   ArgError:
  979.         mov    dx,offset usage_msg
  980.   error:
  981.         mov    ah,9
  982.         int    21h            ; display usage message
  983.         mov    ax,4c01h        ; error code 1
  984.         int    21h            ; terminate program
  985.   DoArgRet:
  986. if DEBUG
  987.         xor    ax,ax
  988.         mov    word ptr phd_dioa,ax
  989.         mov    word ptr StackLow,ax
  990. endif ; DEBUG
  991.         ret
  992. DoArgs        endp
  993.  
  994.  
  995.  
  996.   ArgAlter:
  997.         or    word ptr Flagword,DONT_SETTIME    ; alter time
  998.         mov    di,offset AlterTime
  999.         mov    cl,2
  1000.         call    GetNums
  1001.         mov    AlterTime+4,dx
  1002.         ret
  1003.  
  1004.   ArgDls:
  1005.         cmp    al,'9'            ; daylight saving algorithm
  1006.         jbe    ArgGetAlgPar
  1007.         lodsw
  1008.         mov    dx,ax
  1009.         lodsw
  1010.         mov    di,offset AlgTab-AlgEntryLen
  1011.         cmp    ah,CR
  1012.         jne    ArgNextDls
  1013.         mov    ah,' '
  1014.         dec    si
  1015.   ArgNextDls:
  1016.         add    di,AlgEntryLen
  1017.         cmp    di,offset AlgTabEnd-1
  1018.         ja    ArgDlsRet
  1019.         cmp    dx,[di]
  1020.         jne    ArgNextDls
  1021.         cmp    ax,[di+2]
  1022.         jne    ArgNextDls            
  1023.         mov    AlgPtr,di
  1024.         ret
  1025.   ArgGetAlgPar:
  1026.         mov    di,offset AlgTab
  1027.         mov    AlgPtr,di
  1028.         add    di,4
  1029.         mov    cl,5
  1030.         call    GetNums
  1031.   ArgDlsRet:
  1032.         ret
  1033.  
  1034. if PINGCLIENT
  1035.   ArgEcho:
  1036.         cmp    al,'A'
  1037.         jae    ArgEchoName
  1038.  
  1039.         mov    di,offset EchoTarget    ; echo to a target (ping)
  1040.         call    GetIpNr
  1041.         jnz    ArgEchoRet        
  1042.   ArgEchoMore:
  1043.         cmp    byte ptr [si],','
  1044.         jne    ArgGoodRet
  1045.         inc    si
  1046.         mov    cl,1
  1047.         call    GetNums
  1048.         jmp    short ArgEchoMore
  1049.   ArgEchoRet:
  1050.         ret
  1051.  
  1052.   ArgEchoName:
  1053.         mov    byte ptr EchoTarget,127    ; marker to do dns lookup
  1054.         mov    bx,offset EchoNameBuf
  1055.         lea    di,[bx+1]
  1056.         xor    cx,cx
  1057.   ArgEchoLoop:
  1058.         lodsb
  1059.         cmp    al,' '
  1060.         je    ArgEchoNamEnd
  1061.         cmp    al,CR
  1062.         je    ArgEchoNamEnd
  1063.         cmp    si,bp
  1064.         ja    ArgEchoRet
  1065.         cmp    al,','
  1066.         je    ArgEchoNamEnd
  1067.         cmp    al,'.'
  1068.         jne    ArgEchoNamChar
  1069.         mov    [bx],cl            ; prepend length to string
  1070.         mov    cx,-1
  1071.         mov    bx,di
  1072.   ArgEchoNamChar:
  1073.         stosb
  1074.         inc    cx
  1075.         jmp    short ArgEchoLoop
  1076.  
  1077.   ArgEchoNamEnd:
  1078.         mov    [bx],cl            ; prepend length to string
  1079.         xor    ax,ax
  1080.         stosb
  1081.         inc    ah
  1082.         stosw                ; store type and class
  1083.         stosw
  1084.         dec    si
  1085.         mov    di,offset EchoTarget+4
  1086.         jmp    short ArgEchoMore
  1087. endif ; PINGCLIENT
  1088.  
  1089.   ArgFlag:
  1090.         call    GetNum
  1091.         or    ArgFlags,ax        ; set arg flags
  1092.   ArgGoodRet:
  1093.         xor    ax,ax
  1094.         ret
  1095.  
  1096.   ArgGwy:
  1097.         mov    di,offset DefGwys    ; defult gateways
  1098.         mov    cx,MAXDEFGWYS
  1099.         call    GetIpNums
  1100.         mov    DefGwyNum,ax
  1101.         ret
  1102.  
  1103.   ArgIpnr:
  1104.         or    Flagword,HAVE_MYIPNR    ; my ip nr
  1105.         mov    di,offset MyIpNr
  1106.         call    GetIpNr
  1107.         ret
  1108.  
  1109.   ArgMask:
  1110.         mov    di,offset MyMask    ; net mask
  1111.         call    GetIpNr
  1112.         ret
  1113.  
  1114. if TBLBUILD or PINGCLIENT
  1115.   ArgNameserv:
  1116.         mov    di,offset DefNS        ; defult nameservers
  1117.         mov    cx,MAXDEFNS
  1118.         call    GetIpNums
  1119.         mov    DefNSnum,ax
  1120.         ret
  1121. endif ; TBLBUILD or PINGCLIENT
  1122.  
  1123.   ArgOffset:
  1124.         or    Flagword,HAVE_TIMEOFFSET
  1125.         call    GetNum            ; time offset
  1126.         xchg    ah,al
  1127.         xchg    dh,dl
  1128.         mov    tzoffset,dx
  1129.         mov    tzoffset+2,ax
  1130.         ret
  1131.  
  1132.   ArgPktIntno:
  1133.         call    GetNum            ; packet int number
  1134.         mov    word ptr packet_int_no,ax
  1135.         ret
  1136.  
  1137.   ArgTimeserv:
  1138.         or    Flagword,HAVE_TIMESERVER    ; time server
  1139.         mov    di,offset TimeServIpNr
  1140.         mov    cx,MAXTSERVS
  1141.         call    GetIpNums
  1142.         mov    TservNum,ax
  1143.         ret
  1144.  
  1145.   ArgZoneNam:
  1146.         or    GenFlags,ARGZONE    ; set zone env variable
  1147.         cmp    al,'#'
  1148.         jne    ArgZonePar
  1149.         inc    si
  1150.         jmp    short ArgGoodRet
  1151.   ArgZonePar:
  1152.         or    GenFlags,ARGZONESPEC
  1153.         mov    dl,05fh         ; convert to upper case for name
  1154.         mov    di,offset ZoneString
  1155.         mov    cx,di
  1156.         add    cx,ZONESPACE-2
  1157.   ArgZoneCopyNext:
  1158.         lodsb                ; get next arg char
  1159.         cmp    al,' '            ; end of field?
  1160.         je    ArgZoneCopyRet
  1161.         cmp    al,CR
  1162.         je    ArgZoneCopyRet
  1163.         cmp    si,bp            ; beyond argument string?
  1164.         ja    ArgZoneCopyErr
  1165.         cmp    di,cx            ; too long name?
  1166.         jae    ArgZoneCopyErr
  1167.         cmp    al,'='            ; start of value part?
  1168.         jne    ArgZoneCopy2
  1169.         mov    dl,0ffh         ; any case allowed for 1st value
  1170.         mov    bx,di
  1171.         sub    bx,offset ZoneString-1
  1172.         mov    ZoneVarLen,bx        ; save env name length
  1173.   ArgZoneCopy2:
  1174.         cmp    al,','            ; second value part?
  1175.         jne    ArgZoneCopy3
  1176.         and    dl,07fh         ; any case allowed for 2nd value
  1177.         xor    ax,ax
  1178.         stosw                ; end of string marker
  1179.         mov    al,'$'            ; char for print stop 
  1180.         stosb
  1181.         mov    bx,di
  1182.         sub    bx,offset ZoneString
  1183.         mov    ZoneDstInd,bx        ; remember where 2nd value starts
  1184.         jmp    short ArgZoneCopyNext
  1185.   ArgZoneCopy3:
  1186.         and    al,dl            ; possibly convert to upper case
  1187.         stosb
  1188.         jmp    short ArgZoneCopyNext
  1189.   ArgZoneCopyRet:
  1190.         dec    si
  1191.         cmp    dl,07fh         ; seen two value parts?
  1192.         jne    ArgZoneCopyErr
  1193.         xor    ax,ax
  1194.         stosb                ; end of string marker
  1195.         ret
  1196.  
  1197.   ArgZoneCopyErr:
  1198.         inc    si            ; nonzero ret
  1199.         ret
  1200.  
  1201.  
  1202.  
  1203. ;************************************************************************
  1204. ;*        GetTime
  1205. ;*
  1206. ;* This code first does one turn to query the timeservers to see if any
  1207. ;* one responds within half a second. If none has responded it will do a
  1208. ;* second turn giving each server 2 seconds to respond. As soon as a time
  1209. ;* reply from any server arrives, it stops.
  1210. ;************************************************************************
  1211.  
  1212. GetTime     proc    near
  1213.         call    BufAlloc
  1214.         call    MakeSendDescr
  1215.         mov    [bx].fBotStruc.uUdpDst,2500h    ; 37 = time port
  1216.         mov    [bx].fBotStruc.uUdpSrc,4321    ; my port
  1217.         mov    [bx].dTickTimeout,10    ; 10/18 second
  1218.         mov    [bx].dWaitEvent,GOT_TIMEREPLY
  1219.         mov    [bx].dTimOut2Msg,offset NoTimeServMsg ; timeout msg
  1220.         mov    [bx].dTick2Timeout,2*18
  1221.         mov    dx,offset TservNum
  1222.         mov    [bx].dPktlen,UDPHDRLEN
  1223.         call    SendUdpFind        ; send time requset
  1224.         call    BufRelease
  1225.         ret
  1226. GetTime     endp
  1227.  
  1228.  
  1229. ;========================================================================
  1230.         include settime.asm
  1231.  
  1232.  
  1233.  
  1234. ;************************************************************************
  1235. ;*        SearchAndSub
  1236. ;*
  1237. ;* Find lowest index table entry with value (in seconds) <= DX,AX
  1238. ;* and subtract off table value from DX,AX.
  1239. ;************************************************************************
  1240.  
  1241. SearchAndSub    proc    near
  1242.         call    BinSearch
  1243.         call    AfterSearch
  1244.         ret
  1245. SearchAndSub    endp
  1246.  
  1247.  
  1248.  
  1249. BinSearch    proc    near
  1250.         push    bx
  1251.         mov    bx,cx            ; compute power of 2
  1252.         mov    cx,4            ;   table size
  1253.   BinLenLoop:
  1254.         shl    cx,1
  1255.         cmp    cx,bx
  1256.         jb    BinLenLoop
  1257.  
  1258.         mov    bx,cx            ; start binary search
  1259.   BinLess:
  1260.         sub    bx,cx
  1261.   BinGreater:
  1262.         shr    cx,1
  1263.         cmp    cx,4
  1264.         jb    BinDone         ; no match return
  1265.  
  1266.         add    bx,cx
  1267.         cmp    dx,2[si+bx]
  1268.   BinEval:
  1269.         ja    BinGreater
  1270.         jb    BinLess
  1271.  
  1272.         cmp    ax,[si+bx]
  1273.         ja    BinGreater
  1274.         jb    BinLess
  1275.   BinDone:
  1276.         mov    cx,bx            ; save table index
  1277.         lea    si,[si+bx]        ;   and table entry address
  1278.         pop    bx
  1279.         ret
  1280. BinSearch    endp
  1281.  
  1282.  
  1283.  
  1284. AfterSearch    proc    near
  1285.         sub    ax,[si]         ; subtract seconds
  1286.         sbb    dx,2[si]        ;   by table value
  1287.         shr    cx,1            ; calculate table index
  1288.         shr    cx,1
  1289.         ret
  1290. AfterSearch    endp
  1291.  
  1292.  
  1293.  
  1294. ;**********************************************************************
  1295. ;
  1296. ;    Timezone environment handling
  1297. ;
  1298. ;**********************************************************************
  1299.  
  1300. comment |
  1301. ==========
  1302. tech.notes/pc.code #29, from pmaupin, 3407 chars, Sat Jun  4 22:40:45 1988
  1303. ----------
  1304. TITLE: Finding DOS's master environment pointer
  1305. This is a fragment of code that my SD.COM program uses to find
  1306. the environment.  This fragment is different than most ways of
  1307. finding the environment, in that it finds the MASTER environment block,
  1308. not the current process's parent's environment.
  1309.  
  1310. This is useful in some cases, and has the added advantage that
  1311. it does NOT behave differently when executing under CodeView,
  1312. so you do NOT have to hard-code your system's DOS environment address
  1313. into your program in order to debug it.
  1314.     |
  1315.  
  1316. EnvPtr           EQU         2CH       ; Offset in PSP
  1317.  
  1318. CommandInterrupt   EQU         2EH       ; entry point into first Command.Com
  1319.                        ; through interpreter
  1320.  
  1321. DosSegPtr       EQU         CommandInterrupt * 4 + 2
  1322.  
  1323.  
  1324. ; FindEnvironment is passed:
  1325.  
  1326. ;   DS should point to program PSP
  1327.  
  1328. ; FindEnvironment returns:
  1329.  
  1330. ;   ES points to master environment block, or program's copy if couldn't
  1331. ;           find the master.
  1332.  
  1333. ;   CX is length of block, or 0 if couldn't find the master.
  1334.  
  1335. ; FindEnvironment destroys:
  1336.  
  1337. ;   AX, SI
  1338.  
  1339.  
  1340. FindEnvironment    PROC  NEAR
  1341.            xor     si,si              ; Point to segment 0
  1342.            mov     es,si
  1343.            mov     si, word ptr es:[DosSegPtr]
  1344.            mov     ax,si
  1345.            call  VerifyBlock          ; make sure we've found COMMAND
  1346.            jnz     GotBlock          ; jump if not a good block --
  1347.                           ; use process's environment
  1348.  
  1349.            mov     ax,es:[EnvPtr+10h]   ; get COMMAND's environment ptr
  1350.            or     ax,ax              ; jump if COMMAND has a
  1351.            jnz     MaybeGoodBlock       ; subsidiary environment
  1352.  
  1353.            mov     ax,si              ; If no subsidiary, just use
  1354.            add     ax,cx              ; the allocation block
  1355.            inc     ax              ; immediately after COMMAND
  1356.  
  1357. MaybeGoodBlock:    call  VerifyBlock          ; verify that we have a good
  1358.                           ; one, one way or another
  1359. GotBlock:
  1360.            shl     cx,1              ; multiply by 16 to get
  1361.            shl     cx,1              ; length in bytes
  1362.            shl     cx,1
  1363.            shl     cx,1
  1364.            mov     es,ax
  1365.            ret
  1366.  
  1367.  
  1368. ; VerifyBlock tries to insure that we're pointing to a valid DOS
  1369. ; allocation block.  If not, returns the current process's environment
  1370. ; block.
  1371.  
  1372.  
  1373. VerifyBlock       PROC  NEAR
  1374.            dec     ax             ; get block header into ES
  1375.            mov     es,ax
  1376.            inc     ax
  1377.  
  1378.            cmp     byte ptr es:[0],04Dh     ; make sure signature is valid
  1379.            jnz     UseCurrent
  1380.            cmp     word ptr es:[1],si     ; make sure owner is valid
  1381.            jnz     UseCurrent
  1382.            mov     cx, word ptr es:[3]     ; retrieve the length
  1383.            ret
  1384.  
  1385. UseCurrent:       mov     ax,word ptr ds:[EnvPtr] ; get current process's env
  1386.            xor     cx,cx             ; zero length
  1387.            ret
  1388. VerifyBlock       ENDP
  1389.  
  1390. FindEnvironment    ENDP
  1391.  
  1392. comment |
  1393. So far, this seems to work.  I would welcome any feedback on its
  1394. efficacy, but if the feedback is negative, please give the DOS version
  1395. and a detailed problem description.  Thanks,
  1396. Pat
  1397.     |
  1398.  
  1399. ZoneMsg        db    CR, LF, "Environment variable "
  1400. ZoneString    db    "TZ=+0100",0,0,"$                      "
  1401. ZONESPACE    equ    $-ZoneString
  1402. ZoneVarLen    dw    3
  1403. ZoneStrLen    dw    10
  1404. ZoneDstInd    dw    10
  1405.  
  1406. ;************************************************************************
  1407. ;*        SetZone
  1408. ;*
  1409. ;************************************************************************
  1410.  
  1411. SetZone     proc    near
  1412.         test    GenFlags,ARGZONE    ; anything to SET?
  1413.         jnz    SetZoneInfo
  1414.         ret
  1415.  
  1416.   SetZoneInfo:
  1417.         cld
  1418.         test    GenFlags,ARGZONESPEC    ; extended syntax?
  1419.         jnz    SetZoneSpecial
  1420.  
  1421.         mov    ax,DstAdvance        ; -no, use numeric zones
  1422.         xor    dx,dx            ; compute current time offset
  1423.         mov    cx,tzoffset
  1424.         xchg    ch,cl
  1425.         mov    bx,tzoffset+2
  1426.         xchg    bh,bl
  1427.         sub    ax,bx
  1428.         sbb    dx,cx
  1429.         mov    cl,'+'
  1430.         jns    ZonePositive        ; current time offset sign?
  1431.         mov    cl,'-'
  1432.         not    ax            ; take absolute value
  1433.         not    dx
  1434.         add    ax,1
  1435.         adc    dx,0
  1436.   ZonePositive:
  1437.         mov    di, offset ZoneString
  1438.         add    di,ZoneVarLen
  1439.         mov    [di],cl
  1440.         div    mhour            ; compute hours
  1441.         push    ax
  1442.         mov    ax,dx
  1443.         div    m60b            ;   and minutes
  1444.         xor    ah,ah
  1445.         mov    di,offset ZoneString+3
  1446.         add    di,ZoneVarLen
  1447.         call    PutNumD2        ; put minutes
  1448.         pop    ax
  1449.         sub    di,4
  1450.         call    PutNumD2        ; put hours
  1451.         jmp    short EnvMaster
  1452.  
  1453.   SetZoneSpecial:
  1454.         test    GenFlags,DSTNOW     ; is it normal or dls time?
  1455.         jz    EnvMaster
  1456.         mov    di,offset ZoneString    ; -dls, copy dls name
  1457.         mov    si,di            ;      on top of normal name
  1458.         add    di,ZoneVarLen
  1459.         add    si,ZoneDstInd
  1460.   SetZoneLoop:
  1461.         lodsb
  1462.         stosb
  1463.         cmp    al,0
  1464.         jne    SetZoneLoop
  1465.         stosb
  1466.         mov    al,'$'
  1467.         stosb
  1468.         sub    di,offset ZoneString+1
  1469.         mov    ZoneStrLen,di
  1470.   EnvMaster:
  1471.         call    FindEnvironment     ; Find master environment
  1472.  
  1473.         xor    di,di
  1474.         xor    al,al
  1475.   EnvNext:
  1476.         jcxz    EnvNotFound
  1477.  
  1478.         test    FlagWord,DONT_SETTIME
  1479.         jnz    EnvZonePr
  1480.         push    cx            ; look for TZ=
  1481.         push    di
  1482.         mov    cx,ZoneVarLen
  1483.         mov    si,offset ZoneString
  1484.         repe    cmpsb
  1485.         jnz    EnvNoMatch
  1486.  
  1487.         pop    di            ; if found, remove whole string
  1488.         pop    cx
  1489.         push    cx
  1490.         push    di
  1491.         repne    scasb
  1492.         mov    si,di
  1493.         pop    di
  1494.         push    di
  1495.         push    es
  1496.         pop    ds
  1497.         rep    movsb
  1498.         push    cs
  1499.         pop    ds
  1500.   EnvNoMatch:
  1501.         pop    di
  1502.         pop    cx
  1503.  
  1504.         cmp    byte ptr es:[di],0    ; end of strings?
  1505.         je    EnvEnd
  1506.         repne    scasb            ; -no, skip past this string
  1507.         jmp    short EnvNext
  1508.   EnvEnd:
  1509.         cmp    cx,ZoneStrLen        ; add TZ string to the end
  1510.         jb    EnvNotFound
  1511.         mov    cx,ZoneStrLen
  1512.         mov    si,offset ZoneString
  1513.         rep    movsb
  1514.  
  1515.   EnvZonePr:
  1516.         mov    dx,offset ZoneMsg
  1517.         push    cs
  1518.         pop    ds
  1519.         mov    ah,9
  1520.         int    21h            ; display env var contents
  1521.  
  1522.   EnvNotFound:
  1523.         push    cs            ; restore ds and es
  1524.         push    cs
  1525.         pop    ds
  1526.         pop    es
  1527.         ret
  1528. SetZone     endp
  1529.  
  1530.  
  1531.  
  1532. ;************************************************************************
  1533. ;*        DelayTermin
  1534. ;************************************************************************
  1535.  
  1536. DelayTermin    proc    near
  1537. if RFCC
  1538.         test    ArgFlags,TERM_WAIT+MAKE_TABLE ; want delayed termination?
  1539.         jnz    DelayLoop
  1540.         ret
  1541.   DelayLoop:
  1542.         call    SomeThing2Do        ; ARP or ICMP reply
  1543. if PINGCLIENT
  1544.         call    EchoDisplay        ; show current values
  1545. endif ; PINGCLIENT
  1546.         call    AnyKey
  1547.         jz    DelayLoop        ; second key stops receive
  1548.   DelayCrLf:
  1549. if PINGCLIENT
  1550.         cmp    al,ESCAPE
  1551.         je    DelayNotPing
  1552.         cmp    MsgEchoSweep,'<'    ; show drop size distribution
  1553.         jne    DelayNotPing
  1554.  
  1555.         mov    cx,(1500-20)/20
  1556.         mov    si,offset EchoSizeVec+2
  1557.         mov    word ptr FileBuf,LF*256+CR
  1558.         mov    PutNumFiller,' '
  1559.         mov    ax,21
  1560.   PingNextRow:
  1561.         push    cx
  1562.         push    ax
  1563.         mov    di,offset FileBuf+2
  1564.         mov    PutMinDigits,4
  1565.         call    PutNum
  1566.         mov    PutMinDigits,2
  1567.         mov    al,':'
  1568.         stosb
  1569.         xor    bx,bx
  1570.         mov    cx,20
  1571.   PingNextCol:
  1572.         push    cx
  1573.         mov    al,' '
  1574.         stosb
  1575.         lodsw
  1576.         add    bx,ax
  1577.         call    PutNum
  1578.         pop    cx
  1579.         loop    PingNextCol
  1580.  
  1581.         or    bx,bx
  1582.         jz    PingNoRow
  1583.         mov    byte ptr [di],'$'
  1584.         mov    dx,offset FileBuf
  1585.         mov    ah,9
  1586.         int    21h
  1587.         dec    PingRowCnt
  1588.         jnz    PingNoRow
  1589.         mov    PingRowCnt,22
  1590.   PingDispPause:
  1591.         call    AnyKey
  1592.         jz    PingDispPause
  1593.         cmp    al,ESCAPE
  1594.         jne    PingNoRow
  1595.         pop    ax
  1596.         pop    cx
  1597.         jmp    short DelayNotPing
  1598.   PingNoRow:
  1599.         pop    ax
  1600.         add    ax,20
  1601.         pop    cx
  1602.         loop    PingnextRow
  1603.   DelayNotPing:
  1604. endif ; PINGCLIENT
  1605.         mov    dx,offset CrLf_Msg
  1606.         mov    ah,9
  1607.         int    21h
  1608. if TBLBUILD
  1609.         call    TableWr         ; write HW and IP tbl files
  1610. endif ; TBLBUILD
  1611.  
  1612.   DelayEnd:
  1613. endif ; RFCC
  1614.         ret
  1615. DelayTermin    endp
  1616.  
  1617.  
  1618.  
  1619. ;************************************************************************
  1620. ;*        AnyKey
  1621. ;************************************************************************
  1622.  
  1623. AnyKey        proc    near
  1624.         mov    ah,06h
  1625.         mov    dl,0ffh
  1626.         int    21h            ; any key pressed?
  1627.         ret
  1628. AnyKey        endp
  1629.  
  1630.  
  1631.  
  1632. if PINGCLIENT
  1633. ;========================================================================
  1634.          include ping.asm
  1635. endif ; PINGCLIENT
  1636.  
  1637.  
  1638.  
  1639. if TBLBUILD or PINGCLIENT
  1640.  
  1641. NsStruc     struc
  1642. uNsUdpHdr    UdpStruc    <>
  1643. uNsId        dw    0
  1644. uNsOpwd     dw    0001h            ; do recursion
  1645. uNsQdcount    dw    0100h            ; one question
  1646. uNsAncount    dw    0
  1647. uNsNscount    dw    0
  1648. uNsArcount    dw    0
  1649. uNsQuest    equ    $-uNsUdpHdr
  1650. NsStruc     ends
  1651.  
  1652. ;************************************************************************
  1653. ;*        NameDecode
  1654. ;*
  1655. ;*    Find end of name and change length bytes to dots
  1656. ;************************************************************************
  1657.  
  1658. NameDecode    proc    near
  1659.         lodsb
  1660.         mov    byte ptr [si-1],' '    ; blank 1st length byte
  1661.         jmp    short NameDcTst
  1662.   NameDcLoop:
  1663.         lodsb
  1664.         mov    byte ptr [si-1],'.'    ; change length byte to dot
  1665.   NameDcTst:
  1666.         cmp    al,0c0h            ; compressed?
  1667.         jb    NameDcNorm
  1668.         mov    byte ptr [si],' '
  1669.         inc    si
  1670.         ret
  1671.   NameDcNorm:
  1672.         mov    ah,al
  1673.         or    al,al            ; end of name?
  1674.         jz    NameDcRet        ; -yes, return
  1675.   NameDcSkip:
  1676.         lodsb                ; -no, skip over string
  1677.         or    al,al            ; bad syntax?
  1678.         jz    NameDcRet        ; -yes, better return now
  1679.         dec    ah            ; -no, continue skiping
  1680.         jnz    NameDcSkip    
  1681.         jmp    short NameDcLoop
  1682.   NameDcRet:
  1683.         ret
  1684. NameDecode    endp
  1685.  
  1686.  
  1687.  
  1688. ;************************************************************************
  1689. ;*              NsResolve
  1690. ;*
  1691. ;*    Input:        DX = my udp port
  1692. ;*            AX = Ns Id
  1693. ;*            SI = address of querry string
  1694. ;************************************************************************
  1695.  
  1696. MsgResolve    db    "no response.$"
  1697.  
  1698. NsResolve    proc    near
  1699.         push    bx
  1700.         call    BufAlloc        ; get a big buf
  1701.         mov    cx,SERRNOBUF
  1702.         jz    NsResErr
  1703.  
  1704.         call    MakeSendDescr
  1705.         mov    [di].uUdpDst,3500h
  1706.         mov    [di].uUdpSrc,dx
  1707.         mov    [di].uNsId,ax
  1708.         xor    ax,ax
  1709.         mov    [di].uNsOpwd,1        ; recursion desired
  1710.         mov    [di].uNsQdcount,0100h    ; 1 question
  1711.         mov    [di].uNsAncount,ax
  1712.         mov    [di].uNsNscount,ax
  1713.         mov    [di].uNsArcount,ax
  1714.         mov    [bx].dTick2Timeout,14*18 ; give him 14 seconds 2nd turn
  1715.         mov    [bx].dTimOut2Msg,ax
  1716.         mov    [bx].dWaitEvent,GOT_NSREPLY
  1717.         cmp    dx,1234h
  1718.         je    NsTableBuild
  1719.  
  1720. ;*test        mov    [bx].dWaitEvent,GOT_NSREPLY
  1721.         mov    [bx].dTickResend,4*18    ; resend after 4 seconds
  1722.         mov    [bx].dTickTimeout,2*18    ; give him 2 seconds 1st turn
  1723.         mov    [bx].dTimOut2Msg,offset MsgResolve
  1724.   NsTableBuild:
  1725.         lea    di,[di].uNsQuest    ; copy question
  1726.   NsQloop:
  1727.         lodsb
  1728.         stosb
  1729.         or    al,al
  1730.         jnz    NsQloop
  1731.  
  1732.         movsw                ; copy type and class
  1733.         movsw
  1734.  
  1735.         mov    ax,di            ; compute udp data length
  1736.         mov    si,[bx].dPtrUdp
  1737.         sub    ax,si
  1738.         mov    [bx].dPktLen,ax
  1739.  
  1740.         mov    dx,offset DefNsNum
  1741.         call    SendUdpFind        ; send pkt
  1742.   NsResOK:
  1743.         call    BufRelease
  1744.   NsResErr:
  1745.         or    cx,cx
  1746.         pop    bx
  1747.         ret
  1748. NsResolve    endp
  1749.  
  1750.  
  1751.  
  1752. ;************************************************************************
  1753. ;*              DoNsInterp
  1754. ;************************************************************************
  1755.  
  1756. DoNsInterp       proc    near
  1757.         cld
  1758.         push    cs
  1759.         pop    es
  1760.         mov    di,[bx].dPtrUdp
  1761.         test    [di].uNsOpwd,0080h    ; reply?
  1762.         jnz    NameResReply
  1763.         ret
  1764.  
  1765.   NameResReply:
  1766. if TBLBUILD
  1767.         cmp    [di].uUdpDst,1234h    ; to the tblbuilder?
  1768.         jne    DoNsIntPing
  1769.                 jmp    DoName
  1770. endif ; TBLBUILD
  1771.   DoNsIntPing:
  1772.         mov    cx,[di].uNsAncount
  1773.         xchg    ch,cl
  1774.         cmp    cx,1            ; any answers?
  1775.         jb    NameResNoAnswer
  1776.  
  1777.         lea    si,[di].uNsQuest
  1778.         call    NameDecode        ; decode question string
  1779.         add    si,4            ; skip over type and class
  1780.   NsAnsLoop:
  1781.         call    NameDecode        ; decode answer string
  1782.         mov    ax,[si]            ; get type
  1783.         add    si,9            ; skip over junk
  1784.         cmp    ax,0100h        ; address?
  1785.         je    NsAnsAddr
  1786.  
  1787.         lodsb
  1788.         xor    ah,ah
  1789.         add    si,ax            ; skip over data bytes
  1790.         loop    NsAnsLoop
  1791.  
  1792.         jmp    short NameResNoAnswer
  1793.   NsAnsAddr:
  1794.         cmp    byte ptr [si],4        ; 4 IP bytes here?
  1795.         jne    NameResNoAnswer
  1796.  
  1797.         inc    si            ; copy IP number
  1798.         mov    di,offset EchoTarget
  1799.         movsw
  1800.         movsw
  1801.   NameResNoAnswer:
  1802.         or    Events,GOT_NSREPLY    ; note we've got ns reply
  1803.         ret
  1804. DoNsInterp    endp
  1805.  
  1806. endif ; TBLBUILD or PINGCLIENT
  1807.  
  1808.  
  1809.  
  1810. if TBLBUILD
  1811. ;========================================================================
  1812.         include tblbuild.asm
  1813. endif ; TBLBUILD
  1814.  
  1815. ;************************************************************************
  1816. ;*        Receive buffers                     *
  1817. ;************************************************************************
  1818.  
  1819.         even
  1820. AdrBootpReply    dw    0            ; save address of bootp reply
  1821.  
  1822. FreeBufs LinkHead <offset FreeBufs,offset Freebufs> ; head of free buffer chain
  1823. FreeSmal LinkHead <offset FreeSmal,offset FreeSmal> ; head of free buffer chain
  1824. SendToDo LinkHead <offset SendToDo,offset SendToDo> ; arp reply list
  1825.  
  1826. if RFCC
  1827. IcmpToDo LinkHead <offset IcmpToDo,offset IcmpToDo> ; icmp reply list
  1828. FragList LinkHead <offset FragList,offset FragList> ; fragm reassembly
  1829. endif ; RFCC
  1830.  
  1831. if TBLBUILD
  1832. TblToDo  LinkHead <offset TblToDo, offset TblToDo>  ; build hw addr tbl
  1833. endif ; TBLBUILD
  1834.  
  1835. if TBLBUILD or PINGCLIENT
  1836. NameToDo LinkHead <offset NameToDo,offset NameToDo> ; name server replies
  1837. endif ; TBLBUILD or PINGCLIENT
  1838.  
  1839. EchoNameBuf    equ    $
  1840. EchoSizeVec    equ    EchoNameBuf
  1841. EchoSizeEnd    equ    EchoSizeVec+2*1500
  1842. BlockAdj    =    (EchoSizeEnd-CodeOrg) and 0ffh
  1843.  
  1844. FileBuf     equ    EchoSizeEnd+256-BlockAdj
  1845. BufStart    equ    FileBuf+128        ; buffer pool space
  1846.  
  1847. BufStartSml    equ     BufStart + NBUFS*BUFSIZE
  1848. BufEnd        equ    BufStartSml + NBUFSMALL*BUFSIZESML
  1849.  
  1850.         org    0ff30h            ; from here to ffff is
  1851. StackLow    equ    $            ; non interrupt stack space
  1852.  
  1853. code_s        ends
  1854.         end    start
  1855.  
  1856. ;************************************************************************
  1857. ;*                                    *
  1858. ;*        This is the end                     *
  1859. ;*                                    *
  1860. ;************************************************************************
  1861.